// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
//
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.reports.editor.design.parts;

import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.dengues.reports.editor.design.models.AbstractReportsElement;
import org.dengues.reports.editor.design.request.ReportRequest;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.tools.DragEditPartsTracker;

/**
 * <p>
 * Abstract super class for all report element editPart
 * </p>
 * 
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf Qiang.Zhang.Adolf@gmail.com 2008-2-22 qiang.zhang $
 * 
 */
public abstract class ReportElementEditPart extends AbstractGraphicalEditPart implements PropertyChangeListener {

    private boolean isEdited = false;

    protected Logger logger = Logger.getLogger(ReportElementEditPart.class.getName());

    // private static boolean canDeleteGuide = true;

    /**
     * Constructor
     * 
     * @param model
     */
    public ReportElementEditPart(Object model) {
        super();
        String[] result = this.getClass().getName().split("\\."); //$NON-NLS-1$
        System.out.println(result[result.length - 1] + " >> Created for " //$NON-NLS-1$
                + model);
        setModel(model);

    }

    /**
     * perform edit directly when the request is the corresponding type.
     */
    @Override
    public void performRequest(Request request) {
        if (RequestConstants.REQ_OPEN.equals(request.getType()) || ReportRequest.CREATE_ELEMENT.equals(request.getType())) {
            if (isEdited()) {
                return;
            }
            setEdited(true);
            try {
                performDirectEdit();
            } catch (RuntimeException e) {
                logger.log(Level.SEVERE, e.getMessage(), e);
            }
            setEdited(false);
        }
    }

    protected void performDirectEdit() {
        // do nothing
    }

    private boolean isEdited() {
        return isEdited;
    }

    private void setEdited(boolean isEdited) {
        this.isEdited = isEdited;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.EditPart#activate()
     */
    @Override
    public void activate() {
        if (isActive())
            return;

        super.activate();

        ((AbstractReportsElement) getModel()).addPropertyChangeListener(this);

        getFigure().setFocusTraversable(true);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.EditPart#deactivate()
     */
    @Override
    public void deactivate() {
        if (!isActive())
            return;

        super.deactivate();
        ((AbstractReportsElement) getModel()).removePropertyChangeListener(this);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
     */
    @Override
    protected abstract void createEditPolicies();

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.EditPart#getDragTracker(org.eclipse.gef.Request)
     */
    @Override
    public DragTracker getDragTracker(Request req) {
        DragEditPartsTracker track = new DragEditPartsTracker(this) {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.gef.tools.SelectEditPartTracker#handleButtonDown(int)
             */
            @Override
            protected boolean handleButtonDown(int button) {
                // if (getCurrentViewer() instanceof DeferredGraphicalViewer) {
                // ((DeferredGraphicalViewer) getCurrentViewer()).initStepDat();
                // }
                return super.handleButtonDown(button);
            }
        };
        return track;
    }

    private boolean isDirty = true;

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#refreshVisuals()
     */
    @Override
    public final void refreshVisuals() {
        super.refreshVisuals();
        refreshFigure();
        refreshReportChildren(this);
        // added for must repaint
        getFigure().repaint();
    }

    public void refreshReportChildren(ReportElementEditPart parent) {
        List list = parent.getChildren();
        for (int i = 0; i < list.size(); i++) {
            Object part = list.get(i);
            if (part instanceof ReportElementEditPart) {
                // if (((ReportElementEditPart) part).isDelete()) {
                // continue;
                // }
                ((ReportElementEditPart) part).refreshFigure();
                refreshReportChildren((ReportElementEditPart) part);
            }
        }
    }

    public abstract void refreshFigure();

    /**
     * Marks edit part dirty
     * 
     * @param bool
     * @param notifyParent
     */
    public void markDirty(boolean bool) {
        this.isDirty = bool;
    }

}